<template>
  <!-- <div style="{height:formoption.option.height+'px'}"> -->
    <el-container>
      <el-main class="el_h top_bar">
        <fm-generate-form
          ref="generateForm"
          :data="formoption"
          :remote="remoteFuncs"
          :remote-option="dynamicData"
          v-model="formdata"
          @on-change="onchange"
        >

          <slot v-for="(key2,index) in cfgslotnames" :slot="key2" v-key="index">
            <slot :name="'cfg_'+key2" />
          </slot>
        </fm-generate-form>
        <!-- <slot name='cfg_selectTable'>rwer</slot> -->
      </el-main>
      <el-footer v-show='buttons.length>0' class="footer_box">
        <el-button v-if="buttons.indexOf('save')!=-1" @click="save" :disabled="savebtn_disabled" type="primary" size="mini" >保存</el-button>
        <el-button v-if="buttons.indexOf('reset')!=-1" @click="reset" :disabled="resetbtn_disabled" size="mini">重置</el-button>
        <el-button v-if="buttons.indexOf('close')!=-1" @click="close" :disabled="closebtn_disabled" size="mini">关闭</el-button>
        <el-button v-if="buttons.indexOf('search')!=-1" @click="search" :disabled="searchbtn_disabled" size="mini">搜索</el-button>
        <slot title="winbotton" />
      </el-footer>
    </el-container>
  <!-- </div> -->
</template>
<script>
/**
 *  * 属性
 * option 配置参数
 * buttons save/reset/close/search 其中任意一个或组合
 * data 数据
 * dataUrl 数据加载地址
 * formid 表单id
 * formkey 表单标识
 * templet 模板标识
 * formType 表单类型标识，edit:编辑表单,query：查询表单,list：查看表单,table：列表表单
 * formCols 表单显示列数，默认2列
 * formLayout 表单布局，先只支持grid布局，grid：栅格布局,table：表格布局,tabs：标签布局
 * width 宽度
 * height 高度
 * beforesave 保存前处理方法，返回false 取消保存
 * saveurl 保存地址
 * 事件
 * on-change 变动
 * on-${field}-change 指标变动
 * closehandler 关闭方法，关闭按钮点击会调用
 * searchhandler 搜索方法，搜索按钮点击会调用
 * 方法
 * hide 隐藏  fields
 * display 显示 fields
 * disabled 禁用启用 fields,disabled
 * getData 获取数据
 * save 保存
 * reset 重置
 * close 需配合closehandler使用
 * remote 下拉单选多选配置的方法
 * setData 整体赋值 data ,command :command
 * setFieldData 控件赋值
 */
import request from '@/utils/requestutil'
import {getRealUrl} from '@/utils/httpRequet'
export default {
  name: 'BkFormpanel',
  props: {
    // 配置
    slotnames: {
      type: Array,
      default: () => []
    },
    option: {
      type: Object
    },
    // 按钮
    buttons: {
      type: Array,
      default: () => {
        return []
      }
    },
    //
    data: { type: Object, default: () => { return {} } },
    dataUrl: { type: String, default: 'normalFormsave' },
    saveurl: { type: String },
    loadUrl:{type:String,default:'normaleFormEdit'},
    formid: { type: String },
    formkey: { type: String },
    templet: { type: String },
    formType: { type: String },
    formCols: { type: String },
    formLayout: { type: String },
    width: { type: String },
    height: { type: String },
    aftersave: { type: Function, default: () => { return false } },
    savefunc: {
      type: Function,
      default: null
    },
    beforesave: {
      type: Function,
      default: () => {
        return true
      }
    },
    remote: {
      type: Object,
      default: () => { return {} }
    }
  },
  data() {
    return {
      savebtn_disabled:false,
      resetbtn_disabled:false,
      closebtn_disabled:false,
      searchbtn_disabled:false,
      command:'NEW',//new|update
      cfgslotnames: [],
      dynamicData: {
        formtype: [{ value: '1', label: '表单' }, { value: '2', label: '管理节点' }]
      },
      emptyOption: {
        list: [],
        config: {
          labelWidth: 100,
          labelPosition: 'right',
          size: 'small',
          customClass: '',
          ui: 'element',
          layout: 'horizontal',
          labelCol: 3,
          width: '100%',
          height: ''
        }
      },
      formoption: {
        list: [],
        config: {
          labelWidth: 100,
          labelPosition: 'right',
          size: 'small',
          customClass: '',
          ui: 'element',
          layout: 'horizontal',
          labelCol: 3,
          width: '100%',
          height: ''
        }
      },
      remoteFuncs: {

        dicData(resolve, props) {
          request({
            url: 'dicload',
            urlparam: [props.dicFlag]
          }).then(dt => {

            if (dt.errorCode == '1' && dt.data) {
              resolve(dt.data)
            } else {
              resolve({ key: 'error', 'value': '没有找到数据，请检查字典配置' })
            }
          })
          //  setTimeout(function(){
          //    resolve([{label:'表单',value:'1'},{label:'管理节点',value:'2'}])
          //  },1000)
          // }
        },
        selectMaintable() {
        }
        ,uploadParams:this._uploadParams
      },
      formdata: {
      }
    }
  },
  watch: {
    formid(val){
      this.formoption = this.emptyOption
      this.loadcfg()
    },

    templet(val){
      console.log("templet:"+val)
      this.formoption = this.emptyOption
      this.loadcfg()
    },

    option: {
      handler: function(newval, oldval) {
        if (newval.list) {
          this.formoption.list = newval.list
        }
        this.cfgslotnames = newval.blanks
        if (newval.config) {
          this.formoption.config = Object.assign(
            this.formoption.config,
            newval.config,
            { width: this.width + 'px' }
          )

        }
      },
      deep: true
    },
    data: {
      handler: function(newVal, oldVal) {
        this.$set(this,"formdata",{})
        this.$set(this,"formdata",newVal)
      },
      deep: true,
      immediate: true
    },
    formkey: {
      handler: function(newval) {
        this.formoption = this.emptyOption
        this.loadcfg()
      }
    },
    remote: {
      handler: function(val) {
        this.remoteFuncs=Object.assign({},this.remoteFuncs,val);
        //this.bkapply(val, this.remoteFuncs)
      },
      deep: true,
      immediate: true
    }
  },
  updated() {
    //console.log(this.cfgslotnames)
    // this.$forceUpdate();
  },
  created() {
    if (this.option) {
      // 直接传配置给表单
      if (this.option.list) {
        this.formoption.list = this.option.list
      }
      if (this.option.config) {
        this.formoption.config = this.bkapply(
          this.option.config,
          { width: this.width + 'px' },
          this.formoption.config
        )
      }
    } else if (this.formkey || this.templet) {
      this.loadcfg()
      // 当传formkey时，请示配置，然后亩表单
    }
    if (this.data) {
      // 如果有数据，则填入数据
      this.formdata = this.data
    }
  },
  mounted() {
    this.formoption = this.emptyOption
  },
  methods: {
    setButtonDisabled(btn,disabled){
      this[`${btn}btn_disabled`]=disabled;
    },
    _uploadParams(url){
      let _url=getRealUrl(url,true);
      let param={url:_url,_key:this.formdata._key,form:this.formkey,objectId:this.formdata.id};
      return param
    },
    setFieldData(filedkey, data) {
      this.formdata=this.getData4Search();
      this.$set(this.formdata,filedkey,data);// = data
    },
    loadcfg() {
      const $t = this
      let param={flag: this.formkey };
      console.log("formid:"+this.formid+",formkey:"+this.formkey+",templet:"+this.templet);
      request({
        url: 'getformoption',
        params: { flag: this.formkey,id:this.formid,templet:this.templet,type:this.formType,cols:this.formCols,layout:this.formLayout}
      }).then((data) => {
        let option = data.jsonData
        if (typeof data.jsonData === 'string') option = JSON.parse(option)
        if (!option) {
          option = $t.emptyOption
        }
        $t._option = option
        $t.cfgslotnames = option.blanks
        if (option.list) {
          $t.formoption.list = option.list
        }
        if (option.config) {
          $t.formoption.config = Object.assign(
             $t.formoption.config,
            option.config,
            { width: $t.width + 'px' }
          )
        }
        this.$nextTick(()=>{
          this.$emit("formInited",this)
        })
        // this.formoption=option
      })
    },
    getOption() {
      return this._option || this.option
    },
    setData(data,command='UPDATE') {
      this.command=command;
      if(this.$refs.generateForm==undefined){
        let t=this;
        let s=new Date();
        function setdt(dt){
          if(this.$refs.generateForm){
            t.$set(this,"formdata",dt)
          }else{
            if(new Date().getTime()-s>300000)return;
            setTimeout(function(){
              setdt(dt)
            },20)
          }
        }
        setdt(data);
        return;
      }
      this.$set(this,"formdata",data)
     // this.formdata = data
     // this.$refs.generateForm.setData(data)
    },
    setCommand(command){
      if(command=="NEW"||command=="UPDATE"){
        this.command=command
      }
    },
    save() {
      const $t = this
      this._getData().then((data) => {
        if (data != null) {
          if ($t.beforesave) {
            var s = $t.beforesave(data)
            if (s === false) return
          }
          data.app=this.formdata.app;
          data.sn=this.formdata.sn;
          data._key=this.formdata._key;
          // 保存数据
          if ($t.savefunc) {
            $t.option.savefunc(data)
          } else if ($t.dataUrl) {
            // const submitdata = {}
            // for (const s in data) {
            //   submitdata['vo.string(' + s + ')'] = data[s]
            // }
            request({
              url: $t.dataUrl,
              method: 'post',
              voParam:data,
              data: {form:this.formkey,templet:this.templet,command:this.command}
            }).then((_data) => {
              if(_data.errorCode=='1'){
                this.$message({type:'success',message:"保存成功"});
              }else if(_data.errorCode<0){
                this.$message({type:'error',message:"保存失败"});
              }
              if ($t.aftersave) {
                $t.aftersave(_data, data)
              }
            })
          } else {
          }
        }
      })
    },
    loadData(){
      request({
        url: this.loadUrl,
        method: 'post',
        voParam:this.formdata,
        data: {form:this.formkey}
      }).then(res=>{
        if(res.formData){
          this.command='UPDATE';
           this.setData(res.formData,'UPDATE');

        }
      })
    },
    search() {
      this.$emit('searchhandler', this.getData)
    },
    reset() {
      this.formdata = {}
      this.$refs.generateForm.setData({})
    },
    close() {
      this.$emit('closehandler')
    },
    getData4Search(){
      const s = this.$refs.generateForm.getData4Search()
      return s
    },
    getData() {
      return this._getData()
    },
    async validate() {
      return await this.$refs.generateForm.validate()
    },
    async _getData() {
      // let valied = await this.$refs.generateForm.validate();
      if ( this.validate()) {
        const s = await this.$refs.generateForm.getData()

        return s
      }
      return null
    },
    // 隐藏
    hide(fields) {
      this.$refs.generateForm.hide(fields)
    },
    // 显示
    display(fields) {
      this.$refs.generateForm.display(fields)
    },
    // 不可用
    disabled(fields, disabled) {
      this.$refs.generateForm.disabled(fields, disabled)
    },
    disableItem(fields,item){
      this.$refs.generateForm.setItemDisabled(fields, item)
    },
    onchange(field, value, models) {
      this.$emit('on-change', field, value, this.models)
      this.$emit(`on-${field}-change`, value)
    }
  }
}
</script>
<style scoped>

::deep.fm2-main .el-ssid {
  padding: 0px;
}

::v-deep .el_h .el-form-item--mini .el-form-item__content {
    line-height: 24px;
}
::v-deep .el_h .el-form-item--mini.el-form-item{
  margin-top:16px;
  margin-bottom: 16px;
  margin-right:0px;
}

/* ::v-deep .el_h .el-form-item--small .el-form-item__content{ 
  margin-right:20px;
} */
/* ::v-deep .el_h .el-col .el-form-item--mini.el-form-item{
  margin-top:15px;
  margin-bottom: 15px;
  margin-right:8px;
} */
::v-deep .el-form-item--small.el-form-item{
  margin-top:15px;
  margin-bottom: 15px;
}
::v-deep .el_h .el-row .el-col .el-form-item--mini.el-form-item{
  margin-top:7px;
  margin-bottom: 7px;
}
::v-deep .el_h .el-form-item--small.el-form-item{
  margin-top:7px;
  margin-bottom: 7px;
}


</style>
